#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <event.h>
#include <cfuhash.h>
#include "l.h"

struct event iteratorev;
struct timeval iteratorevinterval = { .tv_sec = 3, .tv_usec = 0 };
struct event_base *base = NULL;

int cnt = 0;
int lasttime = 0;
int ret = 0;
char buf[1024] = {0};
char *dptr = buf;

void iterator_cb(evutil_socket_t fd, short event, void *user_data)
{
    l_d("runing count:--------->%d", cnt);
    cfuhash_table_t *ht = (cfuhash_table_t *)user_data;
    char *key = NULL, *data = NULL;
    size_t key_size = 0, data_size = 0;

    int32_t now = (int32_t)time(NULL);
    if(now - lasttime < 20) { l_d("times not up"); goto timesnotup; }
    if(ret == 0){
        dptr = buf;
        dptr += sprintf(dptr, "{");
        ret = cfuhash_each_data(ht, (void **)&key, &key_size, (void **)&data, &data_size);
        if(ret == 0) { l_d("each:this is null, ret:0"); lasttime = now; }
        else{ l_d("cnt:%d data:%s, ret:%d", cnt, data, ret); dptr += sprintf(dptr, "%s,", data); }
    }
    else{
        ret = cfuhash_next_data(ht, (void **)&key, &key_size, (void **)&data, &data_size);
        if(ret == 0) { l_d("this is null, ret:0"); lasttime = now; }
        else{ l_d("cnt:%d data:%s, ret:%d", cnt, data, ret); dptr += sprintf(dptr, "%s,", data); }
    }

    if(now == lasttime){ l_d("--->publish '%s%d}'", buf, now); }
timesnotup:
    printf("\n");
    cnt += 1;
    event_add(&iteratorev, &iteratorevinterval); //redo
}

int main (int argc, char **argv)
{
    cfuhash_table_t *hash = cfuhash_new_with_initial_size(30);
    cfuhash_set_flag(hash, CFUHASH_FROZEN_UNTIL_GROWS);

    char list[32][2][32];
    size_t i;
    for (i = 0; i < 32; i++) {
        sprintf(list[i][0], "test_var%lu", i);
        sprintf(list[i][1], "value%lu", i);
    }
    //把代码段(字符串常量)添加进去，则不能修改也不能free
    //把栈内一片空间添加进去，则可以修改但请保证生命周期
    //把堆内一片空间添加进去，则可以修改最后用完手动free
    cfuhash_put(hash, "var1", "value1");
    cfuhash_put(hash, "var2", "value2");
    cfuhash_put(hash, "var3", "value3");
    cfuhash_put(hash, "var4", "value4");
    cfuhash_pretty_print(hash, stdout);
    printf("%lu entries, %lu buckets used out of %lu\n\n", cfuhash_num_entries(hash), cfuhash_num_buckets_used(hash), cfuhash_num_buckets(hash));


    //event
    base = event_base_new();
    if (base == NULL) { l_e("event_base_new() failed"); return -1; }
    event_assign(&iteratorev, base, -1, EV_TIMEOUT, iterator_cb, hash);
    event_add(&iteratorev, &iteratorevinterval);
    event_base_dispatch(base);

    l_d(PROG "exiting");
    event_base_free(base);
    cfuhash_destroy(hash);

    return (0);
}
